package manager;

import bean.Request;
import bean.Response;
import config.Config;
import errors.HTTPMethodNotSupportException;
import routers.Routers;
import servlet.Servlet;
import utils.Logger;
import utils.UrlPathUtil;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SocketManager {

    public static void loopForever() throws IOException {
        ExecutorService executorService = Executors.newFixedThreadPool(Config.POOL_SIZE);
        ServerSocket serverSocket = new ServerSocket(Config.PORT);
        while (true) {
            Socket socket = serverSocket.accept();
            executorService.execute(new HttpTask(socket));
        }
    }

    public static class HttpTask implements Runnable {

        private Socket socket;

        public HttpTask(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            Servlet servlet;
            Request request = null;
            Response response = null;

                try {
                    request = new Request(socket.getInputStream());
                    response = new Response(socket.getOutputStream());


                    request.setRemoteIP(socket.getRemoteSocketAddress().toString());
                    request.setLocalIP(socket.getLocalAddress().toString());
                    if (request.isOK() == false) {
                        return;
                    }
                    String fullUrl = request.getRequestUrl();
                    servlet = Routers.getRoutersServlet(UrlPathUtil.getBasePath(fullUrl));

                    if (servlet == null) {
                        servlet = Routers.getRoutersServlet("/404");
                        servlet.init(request, response);
                        servlet.doBefore(request, response);
                        servlet.doError(request, response, new HTTPMethodNotSupportException("找不到资源"));
                        Logger.println(" 请求 ： 404  , " + request.toHeader());
                        return;
                    }

                    servlet.init(request, response);
                    servlet.doBefore(request, response);

                    dispatch(servlet, request, response);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (HTTPMethodNotSupportException e) {
                    e.printStackTrace();
                    servlet = Routers.getRoutersServlet("/403");
                    Logger.println(" 请求 ： 403 , " + request.toHeader());
                    servlet.doError(request, response, e);
                } catch (Exception e) {
                    e.printStackTrace();
                    servlet = Routers.getRoutersServlet("/500");
                    Logger.println(" 请求 ： 500 , " + request.toHeader());
                    servlet.doError(request, response, e);
                }finally {

                    if(!socket.isClosed()){
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
        }

        public void dispatch(Servlet servlet, Request request, Response response) throws HTTPMethodNotSupportException {
            switch (request.getMethod()) {
                case "GET":
                    servlet.doGet(request, response);
                    break;
                case "POST":
                    servlet.doPost(request, response);
                    break;
                case "PUT":
                    servlet.doPut(request, response);
                    break;
                case "DELETE":
                    servlet.doDelete(request, response);
                    break;
            }
            Logger.println(" 请求 ： 200 , " + request.toHeader());
        }
    }
}
